package mongo

import (
	"cgs-server/helper"
	"cgs-server/server"
	"cgs-server/server/cgs/app/models"
	v1 "cgs-server/server/cgs/app/models/v1"
	"cgs-server/server/cgs/app/models/vo"
	"cgs-server/server/cgs/app/store"
	"cgs-server/server/model"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
)

type worksheetInfo struct {
	db             *helper.Mongo
	collectionName string
}

func (w *worksheetInfo) Drop(wg *models.WorksheetInfo) error {
	collectionName := "ws" + wg.Id.Hex()
	return w.db.DropCollection(collectionName)
}

func (w *worksheetInfo) UpdateMany(wg *models.WorksheetInfo, user *model.User, opts v1.UpdateOptions) error {
	filter := opts.GetFilter()
	wg.ResolveFilter(wg, user, &filter)
	set := bson.M{}
	if wg.Name != "" {
		set["name"] = wg.Name
	}
	if wg.AppId != "" {
		set["appId"] = wg.AppId
	}
	if wg.GroupId != "" {
		set["groupId"] = wg.GroupId
	}
	if wg.Config != nil {
		set["config"] = wg.Config
	}
	if wg.Fields != nil {
		set["fields"] = wg.Fields
	}

	wg.ResolveUpdateCondition(wg, user, &set)
	update := bson.M{
		"$set": set,
	}
	_, err := w.db.UpdateMany(w.collectionName, filter, update)
	return err
}

func (w *worksheetInfo) Save(wg *models.WorksheetInfo, user *model.User, opts v1.CreateOptions) error {
	wg.ResolveEntity(wg, user)
	_, err := w.db.InsertOne(w.collectionName, wg)
	return err
}

func (w *worksheetInfo) Get(wg *models.WorksheetInfo, user *model.User, opts v1.GetOptions) (*vo.WorksheetInfo, error) {
	filter := bson.M{}
	if !wg.Id.IsZero() {
		filter["id"] = wg.Id
	}
	wg.ResolveFilter(wg, user, &filter)
	result := &vo.WorksheetInfo{}
	find, err := w.db.FindOne(w.collectionName, filter, result)
	if !find {
		return nil, fmt.Errorf("worksheet info not found: %s", wg.GetId())
	}
	return result, err
}

func (w *worksheetInfo) Update(wg *models.WorksheetInfo, user *model.User, opts v1.UpdateOptions) error {
	filter := opts.GetFilter()
	if !wg.Id.IsZero() {
		filter["id"] = wg.Id
	} else {
		return fmt.Errorf("id is required")
	}
	wg.ResolveFilter(wg, user, &filter)
	set := bson.M{}
	if wg.Name != "" {
		set["name"] = wg.Name
	}
	if wg.AppId != "" {
		set["appId"] = wg.AppId
	}
	if wg.GroupId != "" {
		set["groupId"] = wg.GroupId
	}
	if wg.Icon != "" {
		set["icon"] = wg.Icon
	}
	if wg.Config != nil {
		set["config"] = wg.Config
	}
	if wg.Fields != nil {
		set["fields"] = wg.Fields
	}
	if wg.Hidden != nil {
		set["hidden"] = wg.Hidden
	}
	if wg.AllViewQRCode != "" {
		set["allViewQRCode"] = wg.AllViewQRCode
	}
	if wg.ShareState != nil {
		set["shareState"] = wg.ShareState
	}

	wg.ResolveUpdateCondition(wg, user, &set)
	update := bson.M{
		"$set": set,
	}
	_, err := w.db.UpdateOne(w.collectionName, filter, update)
	return err
}

func (w *worksheetInfo) Delete(wg *models.WorksheetInfo, user *model.User, opts v1.DeleteOptions) error {
	filter := bson.M{}
	if !wg.Id.IsZero() {
		filter["id"] = wg.Id
	}
	wg.ResolveFilter(wg, user, &filter)
	_, err := w.db.DeleteOne(w.collectionName, filter)
	return err
}

func (w *worksheetInfo) List(wg *models.WorksheetInfo, user *model.User, opts v1.ListOptions) (*vo.WorksheetInfoList, error) {
	filter := opts.GetFilter()
	wg.ResolveFilter(wg, user, &filter)
	results := &vo.WorksheetInfoList{}
	err := w.db.FindMany(w.collectionName, filter, results, opts.ResolveFindOptions())
	return results, err
}

func newWorksheetInfoStore(d *datastore) store.WorksheetInfoStore {
	return &worksheetInfo{
		db:             d.db,
		collectionName: server.WorksheetInfoCollectionName,
	}
}
